#include <QVector2D>
#include "minecraftblocklibrary.h"
BlockMeta *MineCraftBlockLibrary::getBlock(BlockMeta::BlockType type)
{
    return m_map.value(type);
}

MineCraftBlockLibrary *MineCraftBlockLibrary::create(QQmlEngine *, QJSEngine *)
{
    auto ret = instance();
    QJSEngine::setObjectOwnership(ret,QJSEngine::CppOwnership);
    return ret;
}

MineCraftBlockLibrary *MineCraftBlockLibrary::instance()
{
    static MineCraftBlockLibrary ret(0);
    return &ret;
}

MineCraftBlockLibrary::MineCraftBlockLibrary(int pri)
{
    registerBlocks();
}

BlockRegister MineCraftBlockLibrary::reg(BlockMeta::BlockType type)
{
    BlockRegister ret(this,type);

    return ret;
}

void MineCraftBlockLibrary::registerBlocks()
{
    reg(BlockMeta::GrassBlock).normal({{3,0},{3,0},{0,0},{2,0},{3,0},{3,0}}).finish();
    reg(BlockMeta::StoneBlock).normal({{1,0}}).finish();
    reg(BlockMeta::DirtBlock).normal({{2,0}}).finish();
    reg(BlockMeta::OakPlank).normal({{4,0}}).finish();
    reg(BlockMeta::BrickBlock).normal({{7,0}}).finish();
    reg(BlockMeta::TNTBlock).normal({{8,0},{8,0},{9,0},{10,0},{8,0},{8,0}}).finish();
    reg(BlockMeta::CobbleStonBlock).normal({{16,0}}).finish();
    reg(BlockMeta::BedRockBlock).normal({{17,0}}).finish();
    reg(BlockMeta::SandBlock).normal({{18,0}}).finish();
    reg(BlockMeta::GravelBlock).normal({{19,0}}).finish();
    reg(BlockMeta::OakBlock).normal({{20,0},{20,0},{21,0},{21,0},{20,0},{20,0}}).finish();
    reg(BlockMeta::IronBlock).normal({{22,0}}).finish();
    reg(BlockMeta::GoldBlock).normal({{23,0}}).finish();
    reg(BlockMeta::DiamondBlock).normal({{24,0}}).finish();
    reg(BlockMeta::GoldOre).normal({{32,0}}).finish();
    reg(BlockMeta::IronOre).normal({{33,0}}).finish();
    reg(BlockMeta::CoalOre).normal({{34,0}}).finish();
    reg(BlockMeta::DiamondOre).normal({{50,0}}).finish();
    reg(BlockMeta::RedstoneOre).normal({{51,0}}).finish();


    reg(BlockMeta::Anvil).triangleMesh(nativeMesh("Anvil")).finish();
    reg(BlockMeta::BigChest).triangleMesh(nativeMesh("BigChest")).finish();
    reg(BlockMeta::Chest).triangleMesh(nativeMesh("Chest")).finish();
    reg(BlockMeta::CobbleStoneFence1).triangleMesh(nativeMesh("CobbleStoneFence1")).finish();
    reg(BlockMeta::CobbleStoneFence2).triangleMesh(nativeMesh("CobbleStoneFence2")).finish();
    reg(BlockMeta::CobbleStoneFence3).triangleMesh(nativeMesh("CobbleStoneFence3")).finish();
    reg(BlockMeta::EnderChest).triangleMesh(nativeMesh("EnderChest")).finish();
    reg(BlockMeta::EndPortal).triangleMesh(nativeMesh("EndPortal")).finish();
    reg(BlockMeta::Fence1).triangleMesh(nativeMesh("Fence1")).finish();
    reg(BlockMeta::Fence2).triangleMesh(nativeMesh("Fence2")).finish();
    reg(BlockMeta::Fence3).triangleMesh(nativeMesh("Fence3")).finish();
    reg(BlockMeta::Ladder).triangleMesh(nativeMesh("Ladder")).finish();
    reg(BlockMeta::Rail1).triangleMesh(nativeMesh("Rail1")).finish();
    reg(BlockMeta::Rail2).triangleMesh(nativeMesh("Rail2")).finish();
    reg(BlockMeta::Torch).triangleMesh(nativeMesh("Torch")).finish();
    reg(BlockMeta::TorchOnWall).triangleMesh(nativeMesh("TorchOnWall")).finish();
    reg(BlockMeta::Vine).triangleMesh(nativeMesh("Vine")).finish();
    reg(BlockMeta::Bed).triangleMesh(nativeMesh("Bed")).finish();

}

QUrl MineCraftBlockLibrary::nativeMesh(QString name)
{
    return QUrl(QStringLiteral("qrc:/MineCraftUtils/meshs/%1.mesh").arg(name));
}

BlockMeta::FaceList BlockMeta::faces() const
{
    return m_faces;
}

void BlockMeta::setFaces(const FaceList &newFaces)
{
    if (m_faces == newFaces)
        return;
    m_faces = newFaces;
    emit facesChanged();
}

QUrl BlockMeta::mesh() const
{
    return m_mesh;
}

void BlockMeta::setMesh(const QUrl &newMesh)
{
    if (m_mesh == newMesh)
        return;
    m_mesh = newMesh;
    emit meshChanged();
}

BlockMeta::BlockAttributes BlockMeta::attribute() const
{
    return m_attribute;
}

void BlockMeta::setAttribute(const BlockAttributes &newAttribute)
{
    if (m_attribute == newAttribute)
        return;
    m_attribute = newAttribute;
    emit attributeChanged();
}

BlockMeta::BlockType BlockMeta::type() const
{
    return m_type;
}

void BlockMeta::setType(const BlockType &newType)
{
    if (m_type == newType)
        return;
    m_type = newType;
    emit typeChanged();
}

BlockRegister &BlockRegister::faces(QList<QVector2D> faces)
{
    m_ret->setFaces(faces);
    return *this;
}

BlockRegister &BlockRegister::normal(QList<QVector2D> f)
{
    this->faces(f);
    attr(BlockMeta::BlockShape);

    return *this;
}

BlockRegister &BlockRegister::triangleMesh(QUrl mesh)
{
    this->mesh(mesh);
    attr(BlockMeta::Transparent);

    return *this;
}

BlockRegister &BlockRegister::mesh(QUrl mesh)
{
    m_ret->m_mesh = mesh;
    return *this;
}

BlockRegister &BlockRegister::attr(BlockMeta::BlockAttribute attribute)
{
    m_ret->m_attribute = attribute;
    return *this;
}

void BlockRegister::finish()
{
    auto ret = m_ret.release();
    origin->m_map[ret->type()] = ret;
}

